import mongoose from 'mongoose';
import joigoose from 'joigoose';
import { NEW_USER } from '@kuiper/auth';

import * as validation from '../common/validation';
import errorCodesBuilder from './helpers/errorCodesBuilder';

const errorCodes = errorCodesBuilder('MongoDB初始化失败');

const Joigoose = joigoose(mongoose);

export default function schemaBuilder(server) {
	Object.entries(validation).forEach(([field, schema]) => {
		if (field.endsWith('WithId')) return;
		const mongoSchema = Joigoose.convert(schema);

		try {
			server.methods.registerMongoModel({
				schema: mongoSchema,
				name: field.slice(0, 1).toUpperCase() + field.slice(1),
			});
		} catch (error) {
			server.log.fatal(
				{ error, tableName: field },
				'Model schema register fail'
			);
		}
	});

	/**
	 * 初始化数据库默认值
	 */
	server.ext('onPostStart', () => {
		server.events.on(NEW_USER, async user => {
			const {
				app: {
					model: { AlertReceiver, AlertGroup },
				},
			} = server;
			server.log.info({ user: user.username }, '初始化新用户告警策略信息');

			try {
				const receiver = await AlertReceiver.findOne({
					uid: user._id,
					isDefault: true,
				}).then(
					x =>
						x ||
						new AlertReceiver({
							name: '默认告警人',
							uid: user._id,
							isDefault: true,
							phone: user.phone,
							phoneVerified: user.phoneVerified,
							email: user.email,
							emailVerified: user.emailVerified,
							wechat: (user.wechat || {}).nickname,
							enable: true,
						})
				);
				await receiver.save();
				await AlertGroup.updateOne(
					{
						uid: user._id,
						isDefault: true,
					},
					{
						name: '默认告警策略',
						uid: user._id,
						isDefault: true,
						receiverIds: [receiver.id],
						// eslint-disable-next-line camelcase
						includeWechat: Boolean(user.wechat?.wx_openid),
						enable: true,
					},
					{ upsert: true }
				);
			} catch (err) {
				const error = errorCodes['[0E]初始化用户默认告警人/策略信息失败'].from(
					err
				);
				server.log.error({ error }, error.rawMessage);
				server.log.fatal({ error, username: user.username }, error.rawMessage);
			}
		});
	});
}
